<?php


namespace Lrental\FeeFormula;


use App\Contracts\CacheKey;
use App\Models\Fee\FeeFormula;
use App\Models\Order\Order;
use App\Models\Order\OrderItem;
use exprlib\Parser;
use Illuminate\Support\Facades\Cache;


class FeeFormulaUtils
{


    public static function getFormulaByAsset(OrderItem $item): ?FeeFormula
    {
        // 1 get all available formulas
        $formulas = Cache::tags([CacheKey::TAG_META])
            ->rememberForever(CacheKey::KEY_FEE_FORMULAS, function () {
                return FeeFormula::all();
            });
        $hittedFormulas = $formulas->filter(function (FeeFormula $formula) use ($item) {
            return (new FormulaCondition($formula->criteria))->test($item);
        });
        if ($hittedFormulas->count() > 0) {
            return $hittedFormulas[0];
        }
        return null;
    }

    public static function calc(OrderItem $orderItem, Order $order): float
    {
        $result = 0;
        $feeFormula = self::getFormulaByAsset($orderItem);
        if (empty($feeFormula)) {
            // default formula : unit price * quantity * discount
            $result = $orderItem->rentalable->price * $orderItem->quantity * $order->discount;
        }else {
            $f = $feeFormula->formula;
            $patterns = array();
            $patterns[0] = '/\{price\}/';
            $patterns[2] = '/\{discount\}/';
            $patterns[1] = '/\{duration\}/';
            $replacements = array();
            $replacements[2] = $orderItem->rentalable->price;
            $replacements[1] = $order->discount;
            $replacements[0] = $order->expect_duration;
            $evalStr =  preg_replace($patterns, $replacements, $f);
            $result = Parser::build($evalStr)->evaluate();
        }
        return $result;
    }
}
